/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.ivybeans.module.completion.ivyfiles;

import com.googlecode.ivybeans.module.completion.IvyCompletionItem;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import org.apache.ivy.Ivy;
import org.apache.ivyde.common.completion.CodeCompletionProposal;
import org.apache.ivyde.common.completion.IvyFileCodeCompletionProcessor;
import org.apache.ivyde.common.model.IvyModel;
import org.apache.ivyde.common.model.IvyModelSettings;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.api.xml.lexer.XMLTokenId;
import org.netbeans.spi.editor.completion.CompletionResultSet;
import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
import org.openide.util.Exceptions;

/**
 *
 * @author xavier
 */
public class CompletionQuery extends AsyncCompletionQuery implements IvyModelSettings {
    private JTextComponent component;
    private Ivy ivy;
    private IvyFileCodeCompletionProcessor processor;
    
    /**
     * Creates a new instance of CompletionQuery
     */
    public CompletionQuery(Ivy ivy) {
        if (ivy == null) {
            this.ivy = new Ivy();
            try {
                this.ivy.configureDefault();
            } catch (Exception ex) {
                Exceptions.printStackTrace(ex);
                this.ivy = null;
            }
        } else {
            this.ivy = ivy;
        }
        processor = new IvyFileCodeCompletionProcessor(new IvyModel(this));
    }
    
    /**
     *
     */
    @Override
    protected void prepareQuery(JTextComponent component) {
        this.component = component;
    }

    @Override
    protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
        try {
            if (ivy == null || !isIvyFile(doc)) {
                return;
            }
            CodeCompletionProposal[] proposals = processor.computeCompletionProposals(
                    processor.getModel().newIvyFile("test", doc.getText(0, doc.getLength()), caretOffset), 
                    caretOffset);
            for (int i = 0; i < proposals.length; i++) {
                CodeCompletionProposal proposal = proposals[i];
                resultSet.addItem(new IvyCompletionItem(
                        proposal.getReplacementOffset(), 
                        proposal.getReplacementString(),
                        proposal.getCursorPosition()));
            }
        } catch (BadLocationException e) {
            
        } finally {
            resultSet.finish();            
        }
    }
    
    private boolean isIvyFile( Document document ) {
        return "ivy-module".equals(getDocRoot(document));
    }

    /**
     * Finds the root element of the xml document.
     */
    public static String getDocRoot(Document document) {
        TokenHierarchy th = TokenHierarchy.get(document);
        TokenSequence ts = th.tokenSequence();
        while(ts.moveNext()) {
            Token nextToken = ts.token();
            if(nextToken.id() == XMLTokenId.TAG) {
                String tagName = nextToken.text().toString();
                if(tagName.startsWith("<"))
                    return tagName.substring(1, tagName.length());
            }
        }
        return null;
    }

    public String getDefaultOrganization() {
        // TODO
        return "";
    }

    public String getDefaultOrganizationURL() {
        // TODO
        return "";
    }

    public Ivy getIvyInstance() {
        return ivy;
    }

    public void logError(String message, Exception e) {
        System.out.println(message);
    }
}
